#pragma once
#include "Utils.h"
#include "BaseObjectWrapper.h"
namespace Smo
{
	using namespace std;
	template<class T>
	class BaseNumberWrapper : public BaseObjectWrapper<T>
	{
	public:
		BaseNumberWrapper(const T& val)
			: BaseObjectWrapper(val)
		{
		}


		virtual wstring ToString() const override
		{
			return to_wstring(mValue);
			
		}

		BaseNumberWrapper(const BaseNumberWrapper& other)
			: BaseObjectWrapper(other.mValue)
		{
		}

		BaseNumberWrapper& operator=(const BaseNumberWrapper& other)
		{
			this->mValue = other.mValue;
			return *this;
		}

		BaseNumberWrapper& operator=(T val)
		{
			this->mValue = val;
			return *this;
		}

		BaseNumberWrapper& operator+=(const BaseNumberWrapper& other)
		{
			this->mValue += other.mValue;
			return *this;
		}

		BaseNumberWrapper& operator+=(T val)
		{
			this->mValue += val;
			return *this;
		}

		BaseNumberWrapper& operator-=(const BaseNumberWrapper& other)
		{
			this->mValue -= other.mValue;
			return *this;
		}

		BaseNumberWrapper& operator-=(T val)
		{
			this->mValue -= val;
			return *this;
		}

		BaseNumberWrapper& operator*=(const BaseNumberWrapper& other)
		{
			this->mValue *= other.mValue;
			return *this;
		}

		BaseNumberWrapper& operator*=(T val)
		{
			this->mValue *= val;
			return *this;
		}

		BaseNumberWrapper& operator/=(const BaseNumberWrapper& other)
		{
			this->mValue /= other.mValue;
			return *this;
		}

		BaseNumberWrapper& operator/=(T val)
		{
			this->mValue /= val;
			return *this;
		}

		T operator+(const BaseNumberWrapper& right) const
		{
			T val = this->mValue;
			val += right.mValue;
			return val;
		}

		BaseNumberWrapper operator+(T right) const
		{
			BaseNumberWrapper val = *this;
			val += right;
			return val;
		}

		T operator-(const BaseNumberWrapper& right) const
		{
			T val = this->mValue;
			val -= right.mValue;
			return val;
		}

		BaseNumberWrapper operator-(T right) const
		{
			BaseNumberWrapper val = *this;
			val -= right;
			return val;
		}
		T operator/(const BaseNumberWrapper& right) const
		{
			T val = this/>mValue;
			val /= right.mValue;
			return val;
		}

		BaseNumberWrapper operator/(T right) const
		{
			BaseNumberWrapper val = *this;
			val /= right;
			return val;
		}
		T operator*(const BaseNumberWrapper& right) const
		{
			T val = this->mValue;
			val *= right.mValue;
			return val;
		}

		BaseNumberWrapper operator*(T right) const
		{
			BaseNumberWrapper val = *this;
			val *= right;
			return val;
		}

	};

	SMO_TYPE_FOR(BaseNumberWrapper<int32_t>, Int32);
	SMO_TYPE_FOR(BaseNumberWrapper<float>, Float);
	SMO_TYPE_FOR(BaseNumberWrapper<int64_t>, Int64);
	SMO_TYPE_FOR(BaseNumberWrapper<double_t>, Double);
}